<?php

namespace App\Services\Accompany;

use App\Enums\AccompanyEnum;
use App\Exceptions\BasicException;
use App\Models\MainDB\Accompany\AccompanyAbility;
use App\Models\MainDB\Accompany\AccompanyCouponUser;
use App\Models\MainDB\Accompany\AccompanyGame;
use App\Models\MainDB\Accompany\AccompanyLabel;
use App\Models\MainDB\Accompany\AccompanyLevel;
use App\Models\MainDB\Accompany\AccompanyOrder;
use App\Models\MainDB\Accompany\AccompanyUser;
use App\Models\MainDB\Accompany\AccompanyUserAdvantageLabel;
use App\Models\MainDB\Config;
use App\Models\MainDB\UserData;
use App\Models\MainDB\UserDevice;
use App\Models\MainDB\UserPhoto;
use App\Models\MainDB\UserRoom;
use App\Repositories\Accompany\AccompanyAbilityRepository;
use App\Repositories\Accompany\AccompanyGameAdvantageLabelRepository;
use App\Repositories\Accompany\AccompanyGameRepository;
// use App\Repositories\RoomFrameRelationRepository;
// use App\Repositories\RoomFrameRepository;
use App\Services\Tools\AmapService;
use App\Services\Tools\RedisService;
class AccompanyGameService
{

    public function getList()
    {
        $games = AccompanyGameRepository::getInstance()->getList(['id','name','picture','bg_picture','min_hot_val','max_hot_val']);
        $data = [];
        foreach ($games as $game) {
            $data[] = [
                'id'         => $game['id'],
                'name'       => $game['name'],
                'picture'    => $game['picture'],
                'bg_picture' => $game['bg_picture'], // 背景图片
                'hot_val'    => mt_rand($game['min_hot_val'], $game['max_hot_val']),
            ];
        }
        return $data;
    }

    /**
     * 获取游戏详情
     * @return array
     */
    public function getDetail($gameId): array
    {
        $game = AccompanyGame::query()->where(['id' => $gameId])->first();
        $priceList = explode(',', $game->price);
        $label = AccompanyLabel::query()->whereRaw("FIND_IN_SET(?,game_id)", [$gameId])->get()->toArray();
        $labelType =   AccompanyGameAdvantageLabelRepository::getInstance()->advantageSelector($gameId);

        return [
            'id'                => $game->id,
            'name'              => $game->name,
            'picture'           => $game->picture,
            'price_list'        => $priceList,
            'level_list'        => explode(',', $game->level),
            'service_list'      => explode(',', $game->service),
            'reduce_price_list' => $priceList,
            'label_list'        => $label,
            'label_type'        => $labelType,

        ];
    }

    // /**
    //  * 获取游戏下达人列表
    //  * @param $userId 当前用户ID
    //  * @param $gameId 游戏ID
    //  * @param $status 状态 0:不限
    //  * @param $sex 性别
    //  * @param $region 区域
    //  * @param $sort 排序
    //  * @param $page 页码
    //  * @param $perPage 单页显示数量
    //  * @return mixed
    //  */
    // public function getAbilityList($userId, $gameId, $status, $sex, $region, $sort, $page, $perPage)
    /**
     * @param $userId
     * @param $gameId
     * @param array $condition
     * @param $sort
     * @param $page
     * @param $perPage
     * @return array|mixed
     */
    public function getAbilityList($userId, $gameId, array $condition, $sort, $page, $perPage)
    {
        $region = $condition[AccompanyEnum::SELECTOR_TYPE_AREA];
        // $sex = $condition[AccompanyEnum::SELECTOR_TYPE_GENDER];
        // $advantage = $condition[AccompanyEnum::SELECTOR_TYPE_ADVANTAGE];
        // $service = $condition[AccompanyEnum::SELECTOR_TYPE_SERVER];
        // $level = $condition[AccompanyEnum::SELECTOR_TYPE_LEVEL];
        // $status = $condition["status"];

        if($gameId == 0 && $sort == 0){
//            return $this->getAbilityLevelList($userId, 1, $condition, $page);
            return $this->getAbilityLevelList($userId, 0, $condition, $page);
        }

        // 首页缓存
        if($region == 0){
            $data = RedisService::getAccompanyUserCache($gameId, $condition, $sort, $page, $perPage);
            if(!empty($data)){
                $couponUser = AccompanyCouponUser::query()->where(['type' => 1, 'status' => 0, 'user_id' => $userId])->first();
                foreach ($data['list'] as &$value) {
                    $price       = $value['initial_price']; // 原本的价格
                    $reducePrice = 0;               // 优惠前的价格
                    $isReduce    = 0;
                    if ($couponUser) {
                        $isReduce    = 1;
                        $reducePrice = $value['initial_price'];
                        $price       = $couponUser->reduce >= $price ? 0 : bcsub($price, $couponUser->reduce, 2);

                    }
                    $value['is_reduce']     = $isReduce;
                    $value['reduced_price'] = str_replace('.00', '', $reducePrice);
                    $value['price']         = str_replace('.00', '', $price);

                }
                return $data;
            }
        }

        $abilityRepo = AccompanyAbilityRepository::getInstance();
        // $userIds = [];
        if ($gameId == 0) {
            // if ($region == 1) { // 获取同城用户
                // try {
                //
                //     [, $userIds] = $this->getUserIdsByUserId($userId);
                // } catch (\Exception $exception) {
                //     Log::error($exception->getMessage());
                // }
            // }
            // $accompanyList = $abilityRepo->page($status, $sex, $region, $sort, $userIds, $page, $perPage);
            // $accompanyList = $abilityRepo->newPage($status, $sex, $region, $sort, $userIds, $page, $perPage);
//            $accompanyList = $abilityRepo->newPage($userId, 1, $condition, $sort, $page, $perPage);
            $accompanyList = $abilityRepo->newPage($userId, 0, $condition, $sort, $page, $perPage);
        } else {
            $accompanyList = $abilityRepo->abilityPage($gameId, $userId, $condition, $page, $perPage);
        }
        $couponUser = AccompanyCouponUser::query()->where(['type' => 1, 'status' => 0, 'user_id' => $userId])->first();
        $data = [];
        $level =AccompanyLevel::query()->get();
        // $frames = RoomFrameRepository::getInstance()->get();
        foreach ($accompanyList->items() as $key => $ability) {
            $onlineInfo = $this->getOnlineInfo($ability['offline_time']);
            $price = $ability['price']; // 最终支付价格
            $reducePrice = 0; // 优惠前的价格
            $isReduce = 0;
            if ($couponUser) {
                $isReduce = 1;
                $reducePrice = $ability['price'];
                $price = $couponUser->reduce >= $price ? 0 : bcsub($price, $couponUser->reduce, 2);
            }
            $level_name = '';
            if ($ability['level_id'] > 3) {
                $levelInfo  = $level->where('id', $ability['level_id'])->first();
                $level_name = $levelInfo['name'];
            }
            //边框
            // $frameId                  = RoomFrameRelationRepository::getInstance()->getFrameId($ability['user_id'],1);
            // $frame                    = RoomFrameRepository::getInstance()->getInfo($frameId, $frames);

            $data[] = [
                'id'            => $ability['id'],
                'sounds'        => $ability['sounds'],
                'sounds_time'   => $ability['sounds_time'],
                'online_sort'   => $ability['online_sort'],
                'game_id'       => $ability['game_id'],
                'game_name'     => $ability['game_name'],
                'game_picture'  => $ability['game_picture'],
                'game_level'    => $ability['game_level'],
                'game_service'  => $ability['game_service'],
                'price'         => str_replace('.00', '', $price),
                'is_reduce'     => $isReduce,
                'reduced_price' => str_replace('.00', '', $reducePrice),
                'label'         => explode(',', $ability['label']),
                'order_count'   => $ability['order_count'], // 接单数量
                'grade'         => $ability['grade'], // 用户评分
                'unit'          => $ability['unit'], // 单位
                'initial_price'       =>$ability['price'], //原本的价格
                'level_name'    => $level_name,
                'introduction'  => $ability['introduction'],
                // 'border_img'  => $frame['border_img'],
                // 'border_tag'  => $frame['border_tag'],
                'user_data'     => [
                    'nickname'      => $ability['nickname'],
                    'user_id'       => $ability['user_id'],
                    'sex'           => $ability['sex'], // 性别
                    'head_picture'  => $ability['head_picture'], // 头像
                    'level'         => 0, // 会员等级
                    'age'           => birthToAge($ability['birthday'], true), // 年龄
                    'mood'          => $ability['mood'], // 心情状态
                    'offline_time'  => $ability['offline_time'], // 在线状态
                    'online_status' => $onlineInfo['online_status'],
                    'online_val'    => $onlineInfo['online_val'],
                    'signature'     => $ability['signature'],
                ],
            ];
            unset($ability[$key]);
        }
        $res = [
            'list'  => $data,
            'total' => $accompanyList->total(),
            "meta"  => [
                "total" => $accompanyList->total(),
                "page"  => $accompanyList->currentPage(),
                "limit" => $accompanyList->perPage(),
                "pageCount"  => ceil($accompanyList->total()/$accompanyList->perPage()),
            ],
        ];
        RedisService::setAccompanyUserCache($gameId, $condition,$sort, $page, $perPage, $res);
        return $res;
    }


    /**
     * 获取达人列表
     * @param $userId
     * @param $status
     * @param $condition
     * @param $page
     * @return array
     */
    public function getAbilityLevelList($userId, $status, $condition, $page): array
    {
        $abilityRepo = AccompanyAbilityRepository::getInstance();
        $accompanyList = $abilityRepo->levelPage($userId, $status, $condition, $page);

        $couponUser = AccompanyCouponUser::query()->where(['type' => 1, 'status' => 0, 'user_id' => $userId])->first();
        $data = [];
        $level =AccompanyLevel::query()->get();
        // $frames = RoomFrameRepository::getInstance()->get();

        foreach ($accompanyList['result'] as $key => $ability) {
            $onlineInfo = $this->getOnlineInfo($ability['offline_time']);
            $price = $ability['price']; // 最终支付价格
            $reducePrice = 0; // 优惠前的价格
            $isReduce = 0;
            if ($couponUser) {
                $isReduce = 1;
                $reducePrice = $ability['price'];
                $price = $couponUser->reduce >= $price ? 0 : bcsub($price, $couponUser->reduce, 2);
            }
            $level_name = '';
            if ($ability['level_id'] > 3) {
                $levelInfo  = $level->where('id', $ability['level_id'])->first();
                $level_name = $levelInfo['name'];
            }

            //边框
            // $frameId                  = RoomFrameRelationRepository::getInstance()->getFrameId($ability['user_id'],1);
            // $frame                    = RoomFrameRepository::getInstance()->getInfo($frameId, $frames);
            // $list[$key]["border_img"] = $frame->border_img;
            // $list[$key]["border_tag"] = $frame->border_tag;

            $data[] = [
                'id'            => $ability['id'],
                'sounds'        => $ability['sounds'],
                'sounds_time'   => $ability['sounds_time'],
                'online_sort'   => $ability['online_sort'],
                'game_id'       => $ability['game_id'],
                'game_name'     => $ability['game_name'],
                'game_picture'  => $ability['game_picture'],
                'game_level'    => $ability['game_level'],
                'game_service'  => $ability['game_service'],
                'price'         => str_replace('.00', '', $price),
                'is_reduce'     => $isReduce,
                'reduced_price' => str_replace('.00', '', $reducePrice),
                'label'         => explode(',', $ability['label']),
                'order_count'   => $ability['order_count'], // 接单数量
                'grade'         => $ability['grade'],               // 用户评分
                'unit'          => $ability['unit'],                // 单位
                'initial_price' => $ability['price'], //原本的价格
                'level_name'    => $level_name,
                'introduction'  => $ability['introduction'],
                // 'border_img'    => $frame['border_img'],
                // 'border_tag'    => $frame['border_tag'],
                'user_data'     => [
                    'nickname'      => $ability['nickname'],
                    'user_id'       => $ability['user_id'],
                    'sex'           => $ability['sex'], // 性别
                    'head_picture'  => $ability['head_picture'], // 头像
                    'level'         => 0, // 会员等级
                    'age'           => birthToAge($ability['birthday'], true), // 年龄
                    'mood'          => $ability['mood'], // 心情状态
                    'offline_time'  => $ability['offline_time'], // 在线状态
                    'online_status' => $onlineInfo['online_status'],
                    'online_val'    => $onlineInfo['online_val'],
                    'level_id'      => $ability['level_id'],
                    'signature'     => $ability['signature'],
                ],
            ];
            unset($ability[$key]);
        }
        return [
            'list'  => $data,
            'total' => $accompanyList['total'],
            "meta"  => [
                "total" => $accompanyList['total'],
                "page"  => (int) $page,
                "pageCount"  => $accompanyList['pageCount'],
                "limit" => 30,
            ],
        ];
    }

    /**
     * 获取用户在线状态
     * @param $offlineTime
     * @return array
     */
    public function getOnlineInfo($offlineTime)
    {
        if ($offlineTime == 0) {
            return ['online_status' => 1, 'online_val' => '在线'];
        }
        $time = time() - $offlineTime;
        if ($time < 60 * 60 * 24) {//没超过1天
            $time = $time / 3600;
            if ($time < 1) {
                $time = $time * 60;
                if ($time < 1) {
                    $time = $time * 60;
                    $onlineVal = floor($time) . '秒前在线';
                } else {
                    $onlineVal = floor($time) . '分钟前在线';
                }
            } else {
                $onlineVal = floor($time) . '小时前在线';
            }
        } else {
            $onlineVal = '24小时前在线';
        }
        return ['online_status' => 0, 'online_val' => $onlineVal];
    }

    /**
     * 获取当前用户的所在区域的所有用户
     * @param $userId
     * @return array
     * @throws \App\Exceptions\BasicException
     */
    public function getUserIdsByUserId($userId)
    {
        $userIds = [];
        $userDevice = UserDevice::query()->where(['user_id' => $userId])->orderBy('id', 'desc')->first();
        $res = (new AmapService())->getRegionByIp($userDevice->ip);
        if ($res->status == 1 && !empty($res->adcode)) {
            $userIds = app('redis')->smembers('city:' . $res->adcode);
        }
        return [$res, $userIds];
    }

    /**
     * 获取用户所在区域
     * @param $userId
     * @return array
     * @throws \App\Exceptions\BasicException
     */
    public function getUserRegion($userId)
    {
        [$userRegion, $userIds] = $this->getUserIdsByUserId($userId);
        return [
            'user_id'     => $userId,
            'user_region' => $userRegion,
            'user_list'   => $userIds,
        ];
    }

    /**
     * 陪玩技能详情
     * @param $currentUserId
     * @param $accompanyId
     * @param $gameId
     * @param $page
     * @param $perPage
     * @return
     */
    public function getAccompany($currentUserId, $accompanyId, $gameId, $page, $perPage,$user)
    {
        $ability = AccompanyAbility::query()
            ->with(['user_data:user_id,nickname,head_picture,sex,birthday', 'accompany_game:id,name,picture,unit,group_name'])
            ->where(['game_id' => $gameId, 'user_id' => $accompanyId, 'status' => 1])
            ->first();
        if (empty($ability)) {
            throw new BasicException(-1, '技能不存在');
        }
        $abilityInfo = (new AccompanyAbilityService())->buildAccompanyData($ability, 'accompany');
        $orders = AccompanyOrder::query()
            ->with(['user_data'])
            ->where("status", ">=", 1)
            ->where('grade','>',0)
            ->where(['anchor_id' => $accompanyId, 'ability_id' => $ability->id])
            ->paginate($perPage, ['*'], 'page', $page);
        $comments = [];
        foreach ($orders->items() as &$order) {
            $userData = $order->user_data;
            $comments[] = [
                'user_id'       => $userData['user_id'],
                'head_picture'  => $userData['head_picture'],
                'nickname'      => $userData['nickname'],
                'comment_label' => array_filter(explode(',', $order['comment_label'])),
                'comment'       => $order->comment,
            ];
        }
        $follow = app('model_follow')->getUserFollow($currentUserId, $accompanyId);
        $isFollow = empty($follow) ? 0 : 1;
        $userPhotos = UserPhoto::query()
            ->select(['id', 'url', 'file_type', 'category'])
            ->where('user_id', $accompanyId)->where('state', 1)
            ->get()
            ->toArray();
        // $canOrder = (new AccompanyOrderService())->getCanOrder($currentUserId); // 是否可以下单
        $moments = $this->getUserMoments($userPhotos, $ability['picture'], $accompanyId, $user);

        //主要职业
        $labelValue =null;
//        $label = AccompanyUserAdvantageLabel::query()
//            ->leftJoin('ln_accompany_game_advantage_label as l', 'l.id', '=', 'ln_accompany_user_advantage_label.label_id')
//            ->where('user_id', $ability['user_id'])
//            ->where('ability_id', $ability['id'])
//            ->pluck('name')->toArray();

        $labelList =AccompanyUserAdvantageLabel::query()
            ->leftJoin('ln_accompany_game_advantage_label as l', 'l.id', '=', 'ln_accompany_user_advantage_label.label_id')
            ->select(['ln_accompany_user_advantage_label.user_id','ln_accompany_user_advantage_label.label_id','l.name'])
            ->where('ability_id', $ability['id'])
            ->get();
        $labelId = $labelList->pluck('label_id')->toArray();
        $abilityInfo['label_id'] = $labelId;
        $label = $labelList->where('user_id', $ability['user_id'])->pluck('name')->toArray();

        $labelName  = implode('/', $label);
        //$game       = AccompanyGame::query()->where('id', $gameId)->first();
        if (!empty($labelName)){
            $labelValue = [
                'name'  => $ability['accompany_game']['group_name'],
                'value' => $labelName
            ];
        }

        $level_name  = '';
        $abilityUser = AccompanyUser::query()->where('user_id', $ability['user_id'])->first();
        if ($abilityUser['level_id'] > 3) {
            $levelInfo  = AccompanyLevel::query()->where('id', $abilityUser['level_id'])->first();
            $level_name = $levelInfo['name'];
        }


        return array_merge($abilityInfo, [
            'is_follow'   => $isFollow,
            'moments'     => $moments,
            // 'can_order'   => $canOrder,
            'user_photos' => $userPhotos,
            'comments'   => $comments,
            'advantage'      => $labelValue,
            'level_name' => $level_name,
            'total'       => $orders->total(),
            "meta"        => [
                "total" => $orders->total(),
                "page"  => $orders->currentPage(),
                "limit" => $orders->perPage(),
            ],
        ]);
    }

    /**
     * 获取用户照片墙
     * @param $userPhotos
     * @param $picture
     * @param $userId
     * @return array
     */
    public function getUserMoments($userPhotos, $picture, $userId, $user = null)
    {
        if(!$user){
            $user = UserData::query()->where(['user_id' => $userId])->first();
        }
        $moments = [];
        $count = count($userPhotos);
        $max = 2;
        $userHeadPicture = $user->head_picture;
        if (empty($picture)) {
            $picture = $userHeadPicture;
        }
        if ($count > $max) {
            $key1 = array_rand($userPhotos);
            $picture1 = $userPhotos[$key1]['url'];
            unset($userPhotos[$key1]);
            $moments = [$picture1, $userPhotos[array_rand($userPhotos)]['url']];
        } else {
            if ($count == 0) {
                $moments = [$userHeadPicture, $userHeadPicture];
            }
            if ($count == 1) {
                $moments = [$userPhotos[0]['url'], $userHeadPicture];
            }
            if ($count == 2) {
                $moments = [$userPhotos[0]['url'], $userPhotos[1]['url']];
            }
            // 随机
            shuffle($moments);
        }
        return array_merge($moments, [$picture]);
    }

    /**
     * 获取系统配置的随机房间ID
     * @return int[]
     */
    public function getRandomRoomId()
    {
        $roomId = 0;
        $roomIds = app('model_config')->getValue('ACCOMPANY_ROOM_ID');
        if (!empty($roomIds)) {
            $roomIds = explode(',', $roomIds);
            // $rid = $roomIds[array_rand($roomIds)];
//            $room = UserRoom::query()->where('room_id' , $rid)->where('password','')->value('id');
            $room = UserRoom::query()->whereIn('room_id' , $roomIds)->where('password','')->pluck('id');
            //$room    = UserRoom::query()->whereIn('room_id',$roomIds)->where('password','')->inRandomOrder()->first();
            if ($room) {
//                $roomId = $room->id;
//                $roomId = $room;
                $roomId = $room->random();
            }
        }
        if($roomId == 0 )throw new BasicException(-1, '暂无房间！');
        return ['room_id' => $roomId];
    }

    /**
     * 获取配置
     * @return void
     */
    public function getConfig($userId,$channel = ''):array
    {
        $key = 'user:accompany:canOrder:'.$userId;
        $showAccompany = app('redis')->get($key);
        if($showAccompany === null){
            $showAccompany = (new AccompanyOrderService())->getCanOrder($userId);
            app('redis')->setex($key,600,$showAccompany);
        }
        $config = app('model_config')->getValue('XIAOMI_ACCOMPANY_OPEN') ?? 0;
        if ((strpos($channel, "小米") !== false) && $config == 0) {
            $showAccompany = 0;
        }
        return [
            'show_accompany' => (int) $showAccompany,
            'show_red' => (int) (new Config())->getValue('SHOW_ROOM_RED') ?: 0,
            'show_airdrop' =>(int) (new Config())->getValue('SHOW_ROOM_AIRDROP') ?: 0,
        ];
    }


}
